using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Drawing;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OleDb;
using Forecast.Database;
using Forecast.Business;
using System.Collections.Generic;
using Image=System.Web.UI.WebControls.Image;

public delegate void ActiveOffersChangedEventHandler(object sender, EventArgs e);

public partial class controls_grids_ActiveOffers : System.Web.UI.UserControl
{
    #region Variables

    public event ActiveOffersChangedEventHandler ActiveOffersChanged;
    private bool _hasAnyActiveOffers;
    
    #endregion
    #region Interface

    public void BindData(int predictionId)
    {
        Load loader = new Load(ConfigurationManager.ConnectionStrings["ForecastDB"].ConnectionString);
        
        Prediction prediction = loader.GetPrediction(predictionId);
        if (prediction.IsClosed || prediction.EndDate < DateTime.Today)
        {
            GridView1.Visible = false;
            _panel.Visible = false;
            return;
        }

        IList<Offer> offers = loader.GetActiveOffers(prediction);
        GridView1.DataSource = offers;
        GridView1.DataBind();
        if (offers.Count == 0)
        {
            _hasAnyActiveOffers = false;
            _noGridText.Text = string.Format("<b>{0}</b><br/>", "There are currently no active offers.");
            _panel.Visible = false;
        }
        else
        {
            _hasAnyActiveOffers = true;
            _panel.GroupingText = "Marketplace";
        }
    }

    #endregion
    #region Events

    protected string GetTotalPrice(int numPredictions, int pricePerPrediction)
    {
        int totalPrice = numPredictions * pricePerPrediction;
        return String.Format("{0:#,0}", totalPrice);
    }

    public bool HasAnyActiveOffers()
    {
        return _hasAnyActiveOffers;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        GridView1.RowCommand += new GridViewCommandEventHandler(GridView1_RowCommand);
    }

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        int offerId = Int32.Parse( e.CommandArgument.ToString());
        Load loader = new Load(ConfigurationManager.ConnectionStrings["ForecastDB"].ConnectionString);
        Offer offer = loader.GetOffer(offerId);

        Activity activity = new Activity(ConfigurationManager.ConnectionStrings["ForecastDB"].ConnectionString);
                
        switch (e.CommandName)
        {
            case "DoBuy":
            case "DoSell":
                AcceptOffer(activity, offer);
                break;
            case "DoCancel":
                CancelOffer(activity, offer);
                break;
            default:
                break;
        }        
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row == null)
            return;        

        if (e.Row.DataItem == null)
            return;

        Load loader = new Load(ConfigurationManager.ConnectionStrings["ForecastDB"].ConnectionString);

        Forecast.Database.Offer offer = e.Row.DataItem as Forecast.Database.Offer;

        Prediction prediction = loader.GetPrediction(offer.PredictionId);
        Player acceptor = loader.GetPlayer(UserHelper.GetUserId(Page.User.Identity.Name));
        Holding acceptorHolding = loader.GetHolding(acceptor, prediction);

        if (offer == null)
            return;
        OfferAction action = offer.GetDefaultActionForPlayer(acceptor);
        bool canPerformAction = offer.CanPerformDefaultAction(acceptor, acceptorHolding);

        foreach (TableCell cell in e.Row.Cells)
        {
            CheckCellForAction(cell, action, canPerformAction, offer);
            CheckCellForImage(cell, action);
        }
    }

    #endregion
    #region Helper methods

    private void CheckCellForImage(TableCell cell, OfferAction action)
    {
        foreach (Control control in cell.Controls)
        {
            if (control is Image)
            {
                SetVisibilityOnImages(control as Image, action);
            }
        }
    }

    private void CheckCellForAction(TableCell cell, OfferAction action, bool canPerformAction, Offer offer)
    {
        foreach (Control control in cell.Controls)
        {
            if (control is LinkButton)
            {
                SetVisibilityOnLinkButtons(control as LinkButton, action, canPerformAction, offer);
            }
        }
    }

    private void SetVisibilityOnImages(Image image, OfferAction action)
    {
        switch (image.ID)
        {
            case "_imageBuy":
                if (action != OfferAction.Buy)
                    image.Visible = false;
                break;
            case "_imageSell":
                if (action != OfferAction.Sell)
                    image.Visible = false;
                break;
            case "_imageCancel":
                if (action != OfferAction.Cancel)
                    image.Visible = false;
                break;
            default:
                break;
        }
    }

    private void SetVisibilityOnLinkButtons(LinkButton linkButton, OfferAction action, bool canPerformAction, Offer offer)
    {
        switch (linkButton.Text)
        {
            case "Buy":
                if (action != OfferAction.Buy)
                    linkButton.Visible = false;
                break;
            case "Sell":
                if (action != OfferAction.Sell)
                    linkButton.Visible = false;
                break;
            case "Cancel":
                if (action != OfferAction.Cancel)
                    linkButton.Visible = false;
                if (offer.IsBuy) 
                    linkButton.Text = "Cancel your offer to buy";
                else
                    linkButton.Text = "Cancel your offer to sell";
                break;
        }

        linkButton.Enabled = canPerformAction;
        if (!linkButton.Enabled)
        {
            linkButton.Font.Underline = true;
            linkButton.ForeColor = Color.Gray;

        }
    }

    private void AcceptOffer(Activity activity, Offer offer)
    {
        AcceptOfferParams acceptParams = new AcceptOfferParams();
        acceptParams.OfferId = offer.Id;
        acceptParams.PlayerId = UserHelper.GetUserId(Page.User.Identity.Name);
        acceptParams.NumPredictions = offer.NumPredictions;
        activity.AcceptOffer(acceptParams);
        if (ActiveOffersChanged != null)
        {
            ActiveOffersChanged(this, null);
        }
    }

    private void CancelOffer(Activity activity, Offer offer)
    {
        activity.RemoveOffer(offer.Id);
        if (ActiveOffersChanged != null)
        {
            ActiveOffersChanged(this, null);
        }
    }

    #endregion
}
